#include "stdafx.h"
#include "Converter.h"

Converter::Converter()
{

}

Converter::~Converter()
{

}

int Converter::ConvertOBJ(CString filePath)
{
	std::ifstream stream(filePath);
	stream.clear();

	unsigned int numVertices = 0;
	unsigned int numTexcoords = 0;
	unsigned int numNormals = 0;
	unsigned int numIndicies = 0;

	std::string buffer = "";

	while (!stream.eof())
	{
		getline(stream, buffer);

		if (buffer.substr(0,2) == "v ")
			numVertices++;
		if (buffer.substr(0,2) == "vt")
			numTexcoords++;
		if (buffer.substr(0,2) == "vn")
			numNormals++;
		if (buffer.substr(0,1) == "f")
			numIndicies++;
	}

	stream.close();

	m_vertices = new float[numVertices*3];
	m_texcoords = new float[numTexcoords*3];
	m_normals = new float[numNormals*3];
	m_indicies = new int[numIndicies*9];

	int test = numVertices;

	stream.open(filePath);
	stream.clear();

	unsigned int vC, nC, tC, fC;
	nC = vC = tC = fC = 0;

	while (!stream.eof())
	{
		buffer = "";
		getline(stream, buffer);
		std::istringstream line(buffer);
		std::string temp;
		std::string S1, S2, S3;

		if (buffer.substr(0, 1) != "#")
		{
			if (buffer.substr(0, 2) == "v ")
			{
				line >> temp >> S1 >> S2 >> S3;
				m_vertices[vC] = (float)atof(S1.c_str());
				m_vertices[vC+1] = (float)atof(S2.c_str());
				m_vertices[vC+2] = (float)atof(S3.c_str());

				vC+=3;
			}
			else if (buffer.substr(0, 2) == "vt")
			{
				line >> temp >> S1 >> S2 >> S3;
				m_texcoords[tC] = (float)atof(S1.c_str());
				m_texcoords[tC+1] = (float)atof(S2.c_str());
				m_texcoords[tC+2] = (float)atof(S3.c_str());

				tC+=3;
			}
			else if (buffer.substr(0, 2) == "vn")
			{
				line >> temp >> S1 >> S2 >> S3;
				m_normals[nC] = (float)atof(S1.c_str());
				m_normals[nC+1] = (float)atof(S2.c_str());
				m_normals[nC+2] = (float)atof(S3.c_str());

				nC+=3;
			}
			else if(buffer.substr(0,1) == "f")  {
				line >> temp >> S1 >> S2 >> S3;

				int sPos = 0;
				int ePos = sPos;
				std::string temp;
				ePos = (int)S1.find_first_of("/");
				//we have a line with the format of "f %d/%d/%d %d/%d/%d %d/%d/%d"
				if(ePos != std::string::npos)  {
					temp = S1.substr(sPos, ePos - sPos);
					m_indicies[fC] = (int)atof(temp.c_str());

					sPos = ePos+1;
					ePos = (int)S1.find("/", sPos);
					temp = S1.substr(sPos, ePos - sPos);
					m_indicies[fC+1] = (int)atof(temp.c_str());

					sPos = ePos+1;
					ePos = (int)S1.length();
					temp = S1.substr(sPos, ePos - sPos);
					m_indicies[fC+2] = (int)atof(temp.c_str());
				}

				sPos = 0;
				ePos = (int)S2.find_first_of("/");
				//we have a line with the format of "f %d/%d/%d %d/%d/%d %d/%d/%d"
				if(ePos != std::string::npos)  {
					temp = S2.substr(sPos, ePos - sPos);
					m_indicies[fC+3] = (int)atof(temp.c_str());

					sPos = ePos + 1;
					ePos = (int)S2.find("/", sPos+1);
					temp = S2.substr(sPos, ePos - sPos);
					m_indicies[fC+4] = (int)atof(temp.c_str());

					sPos = ePos + 1;
					ePos = (int)S2.length();
					temp = S2.substr(sPos, ePos - sPos);
					m_indicies[fC+5] = (int)atof(temp.c_str());
				}

				sPos = 0;
				ePos = (int)S3.find_first_of("/");
				//we have a line with the format of "f %d/%d/%d %d/%d/%d %d/%d/%d"
				if(ePos != std::string::npos)  {
					temp = S3.substr(sPos, ePos - sPos);
					m_indicies[fC+6] = (int)atof(temp.c_str());

					sPos = ePos + 1;
					ePos = (int)S3.find("/", sPos+1);
					temp = S3.substr(sPos, ePos - sPos);
					m_indicies[fC+7] = (int)atof(temp.c_str());

					sPos = ePos + 1;
					ePos = (int)S3.length();
					temp = S3.substr(sPos, ePos - sPos);
					m_indicies[fC+8] = (int)atof(temp.c_str());
				}

				fC+=9;
			}
		}
	}
	stream.close();

	std::string newString = (((std::string)filePath).substr(0, filePath.GetLength()-4))+".msh";
	std::ofstream fout(newString.c_str(), std::ios::binary);

	//Here we go with the sorting

	unsigned short face = 0;
	std::vector<int*> tempVec;

	for (int j = 0; j < (int)fC; j+=3)
	{
		int* vals = new int[3];
		vals[0] = m_indicies[j];
		vals[1] = m_indicies[j+1];
		vals[2] = m_indicies[j+2];

		if (!ContainFace(vals, tempVec))
		{
			tempVec.push_back(vals);

			m_vertexArray.push_back(m_vertices[((vals[0] - 1) * 3) + 0]);
			m_vertexArray.push_back(m_vertices[((vals[0] - 1) * 3) + 1]);
			m_vertexArray.push_back(m_vertices[((vals[0] - 1) * 3) + 2]);

			m_texcoordArray.push_back(m_texcoords[((vals[1] - 1) * 3) + 0]);
			m_texcoordArray.push_back(m_texcoords[((vals[1] - 1) * 3) + 1]);
			m_texcoordArray.push_back(m_texcoords[((vals[1] - 1) * 3) + 2]);

			m_normalArray.push_back(m_normals[((vals[2] - 1) * 3) + 0]);
			m_normalArray.push_back(m_normals[((vals[2] - 1) * 3) + 1]);
			m_normalArray.push_back(m_normals[((vals[2] - 1) * 3) + 2]);

			m_indiceArray.push_back(face); face++;
		}
		else
		{
			int index = FindIndex(vals, tempVec);
			if (index == -1)
			{
				//Error code here
			}
			else
			{
				m_indiceArray.push_back(index);
			}
		}
	}

	//sorting done

	std::vector<float>::iterator myIter;
	int array_size = 0;
	int tempcount = 0;
	array_size = (int)m_vertexArray.size();
	fout.write((char*)(&array_size), sizeof(array_size));
	for (myIter = m_vertexArray.begin(); myIter != m_vertexArray.end(); myIter++)
	{
		float a = *myIter;
		fout.write((char*)(&a), sizeof(float));
		tempcount++;
	}
	array_size = (int)m_texcoordArray.size();
	fout.write((char*)(&array_size), sizeof(array_size));
	for (myIter = m_texcoordArray.begin(); myIter != m_texcoordArray.end(); myIter++)
	{
		float a = *myIter;
		fout.write((char*)(&a), sizeof(a));
	}
	array_size = (int)m_normalArray.size();
	fout.write((char*)(&array_size), sizeof(array_size));
	for (myIter = m_normalArray.begin(); myIter != m_normalArray.end(); myIter++)
	{
		float a = *myIter;
		fout.write((char*)(&a), sizeof(a));
	}
	array_size = (int)m_indiceArray.size();
	fout.write((char*)(&array_size), sizeof(array_size));
	std::vector<int>::iterator myIntIter;
	for (myIntIter = m_indiceArray.begin(); myIntIter != m_indiceArray.end(); myIntIter++)
	{
		int b = *myIntIter;
		fout.write((char*)(&b), sizeof(b));
	}

	stream.close();

	m_vertexArray.clear();
	m_texcoordArray.clear();
	m_normalArray.clear();
	m_indiceArray.clear();
	
	delete m_vertices;
	delete m_texcoords;
	delete m_normals;
	delete m_indicies;

	return 0;

}

int Converter::FindIndex(int *vals, std::vector<int*> &tempVec)
{
	for (int i = 0; i < (int)tempVec.size(); i++)
	{
		int *temp = tempVec.at(i);

		if (temp[0] == vals[0] &&
			temp[1] == vals[1] &&
			temp[2] == vals[2])
			return i;
	}

	return -1;
}

bool Converter::ContainFace(int *vals, std::vector<int*> &tempVec)
{
	if (tempVec.size() == 0)
	{
		return false;
	}
	else
	{
		for (int i = 0; i < (int)tempVec.size(); i++)
		{
			int *temp = tempVec.at(i);

			if (temp[0] == vals[0] &&
				temp[1] == vals[1] &&
				temp[2] == vals[2])
				return true;
		}
		return false;
	}
	
}